<template>
  <div id="home" class="home">
    <v-md-editor :include-level="[1, 2, 3, 4, 5, 6]" :default-fullscreen="fullscreen" v-model="text" :left-toolbar="leftToolbar" :disabled-menus="[]" @upload-image="handleUploadImage" @save="save" @fullscreen-change="fullscreenChange" :before-preview-change="beforeHtml"></v-md-editor>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted } from 'vue';
  import prettier from 'prettier/standalone';
  import mdParser from 'prettier/parser-markdown';
  import htmlParser from 'prettier/parser-html';
  import yamlParser from 'prettier/parser-yaml';
  import babelParser from 'prettier/parser-babel';
  import tsParser from 'prettier/parser-typescript';
  import { useMessage, useDialog } from 'naive-ui';
  const { dirname, basename, join } = require('path');
  const { outputFile, writeFileSync, copySync, removeSync, existsSync, readFileSync } = require('fs-extra');
  const { dialog, getCurrentWindow, app, getGlobal } = require('@electron/remote');

  // const leftToolbar = ref('undo redo clear | h bold italic strikethrough quote | ul ol table hr | link image code | tip emoji todo-list | save');
  const leftToolbar = ref('undo redo clear | h bold italic strikethrough quote | ul ol table hr | link image code | emoji todo-list | save');
  const text = ref('');
  let mdPath = ref('');
  let fullscreen = ref(false);
  const message = useMessage();
  const nDialog = useDialog();
  const userData = app.getPath('userData');
  const time = ref(0);
  console.log('用户数据目录', userData);

  //图片上传
  function handleUploadImage(event: Event, insertImage: any, files: Array<File>) {
    if (files.length > 1) {
      message.warning('一次只能上传一张图片');
      return;
    } else if (files.length == 0) {
      return;
    } else {
      const file = files[0];
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = (e: any) => {
        //base64转文件流
        const base64 = e.target.result;
        const base64Data = base64.replace(/^data:image\/\w+;base64,/, '');
        const dataBuffer = Buffer.from(base64Data, 'base64');
        let filePath = '';
        const timestamp = new Date().getTime();
        //获取后缀名
        const ext = file.name.split('.').pop();

        if (mdPath.value !== '') {
          //获取md文件名称
          const mdName = basename(mdPath.value, '.md');
          filePath = join(dirname(mdPath.value), mdName, `${timestamp}.${ext}`);
        } else {
          //获取当前时间戳

          if (time.value === 0) {
            time.value = timestamp;
          }
          filePath = join(app.isPackaged ? userData : process.cwd(), '.markdown-k', 'temp', 'images', String(time.value), 'images', `${timestamp}.${ext}`);
        }
        outputFile(filePath, dataBuffer, (err: any) => {
          if (err) {
            message.error('图片上传失败', err);
            return;
          } else {
            //
            insertImage({
              url: `${mdPath.value !== '' ? basename(mdPath.value, '.md') : 'images'}/${timestamp}.${ext}`,
              desc: ''
            });
          }
        });
      };
    }
  }

  //保存md文件
  async function save() {
    let keep = await handleSuccess();
    if (!keep) return;

    if (mdPath.value !== '') {
      try {
        writeFileSync(mdPath.value, text.value);
        message.success('保存成功');
      } catch (e: any) {
        message.error('保存失败,请检查文件是否被占用或被设置为只读');
      }

      return;
    }

    dialog
      .showSaveDialog({
        title: '保存文件',

        defaultPath: join(app.getPath('desktop')),
        filters: [{ name: 'Markdown', extensions: ['md'] }]
      })
      .then((res: any) => {
        if (res.filePath) {
          try {
            writeFileSync(res.filePath, text.value);
            mdPath.value = res.filePath;
            //保存图片
            if (time.value !== 0) {
              const oldPath = join(app.isPackaged ? userData : process.cwd(), '.markdown-k', 'temp', 'images', String(time.value), 'images');
              const newPath = join(dirname(res.filePath), 'images');

              try {
                copySync(oldPath, newPath, { overwrite: true });
                removeSync(oldPath);
                time.value = 0;
              } catch (e: any) {
                message.error('图片保存失败', e);
                return;
              }
            }
            message.success('保存成功');
          } catch (error: any) {
            message.error('保存失败,请检查文件是否被占用或被设置为只读');
            return;
          }
        }
      });
  }

  let win = getCurrentWindow();
  // 全屏切换
  function fullscreenChange(isFullscreen: boolean) {
    if (isFullscreen) {
      win.setFullScreen(true);
    } else {
      win.setFullScreen(false);
    }
  }
  if (win.isFullScreen()) {
    fullscreen.value = true;
  } else {
    fullscreen.value = false;
  }

  // 保存提示
  function handleSuccess() {
    return new Promise((resolve, reject) => {
      nDialog.success({
        title: '提示',
        content: `确定要保存${mdPath.value === '' ? '' : '到 "' + mdPath.value + '" '}吗？`,
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => {
          resolve(true);
        },
        onNegativeClick: () => {
          resolve(false);
        }
      });
    });
  }
  // 解析md文件
  function beforeHtml(text: string, next: any) {
    // console.log(text);

    // 解析md文件图片使用base64
    let reg = /!\[(.*?)\]\((.*?)\)/g;
    let result = text.match(reg);
    if (result) {
      result.forEach(item => {
        let arr = item.split('(');
        let imgPath = arr[1].replace(/\)/g, '');
        //判断是不是http、https、ftp、base64的图片
        if (imgPath.indexOf('http') === 0 || imgPath.indexOf('https') === 0 || imgPath.indexOf('ftp') === 0 || imgPath.indexOf('data:image') === 0) {
          return;
        }
        // 读取文件相对mdPath文件的路径
        let imgpath = join(dirname(mdPath.value), imgPath);
        if (mdPath.value === '') {
          imgpath = join(app.isPackaged ? userData : process.cwd(), '.markdown-k', 'temp', 'images', String(time.value), imgPath);
        }
        //imgpath url 中文解码
        imgpath = decodeURI(imgpath);
        //判断文件是否存在
        if (existsSync(imgpath)) {
          //读取文件
          let img = readFileSync(imgpath);
          let base64 = img.toString('base64');
          text = text.replace(item, `![${arr[0]}](data:image/png;base64,${base64})`);
        }
      });
    }
    next(text);
  }

  onMounted(() => {
    // div 是目标对象 的id
    const div = document.getElementById('home') as HTMLElement;
    //文件拖拽监听事件
    div.addEventListener('drop', function (event) {
      let fileName = event.dataTransfer?.files[0].name.split('.')[1];

      if (fileName === 'md') {
        mdPath.value = event.dataTransfer?.files[0].path as string;
        text.value = '';
      }
    });

    // 生产环境 判断是不是通过md文件打开的
    console.log('是不是生产环境：', app.isPackaged);
    if (app.isPackaged) {
      let dataObj = getGlobal('process').argv;
      if (dataObj[1]) {
        // 刷新不获取文件
        if (sessionStorage.getItem('open-file') === dataObj[1]) {
          return;
        }
        //获取文件后缀名
        let suffix = dataObj[1].substr(dataObj[1].lastIndexOf('.') + 1);
        if (suffix === 'md') {
          mdPath.value = dataObj[1];
          let dataText = readFileSync(mdPath.value, 'utf-8');
          text.value = dataText;
          sessionStorage.setItem('open-file', mdPath.value);
        }
        // else {
        //   message.error(`不支持直接打开${suffix}格式文件`);
        // }
      }
    }
  });

  // 监听按键按下事件
  document.onkeydown = event => {
    if (event.altKey && event.shiftKey && event.key === 'F') {
      // 阻止默认行为（避免浏览器开启查找功能）
      event.preventDefault();

      // 调用格式化代码函数
      formatCode();
    }
  };

  function formatCode() {
    // 使用Prettier格式化代码
    const formattedCode = prettier.format(text.value, {
      parser: 'mdx',
      plugins: [mdParser, htmlParser, yamlParser, babelParser, tsParser],
      // 格式化选项
      semi: false,
      tabWidth: 2,
      singleQuote: true,
      printWidth: 100,
      trailingComma: 'none',
      useTabs: false,
      proseWrap: 'preserve',
      arrowParens: 'avoid',
      bracketSpacing: true,
      endOfLine: 'auto',
      quoteProps: 'consistent'
    });
    // 格式化代码
    text.value = formattedCode;
  }
  // 使用默认浏览器打开链接
  document.addEventListener('click', e => {
    //  @ts-expect-error
    if (e.target?.tagName === 'A') {
      //  @ts-expect-error
      if (e.target?.href) {
        e.preventDefault();
        //@ts-expect-error
        require('electron').shell.openExternal(e.target?.href);
      }
    }
  });
</script>
<style scoped lang="scss">
  .home {
    height: calc(100vh - 30px);
    .v-md-editor {
      height: 100%;
      overflow: hidden;
      background-color: var(--backgroundColor) !important;
      // 目录导航
      :deep(.v-md-editor__left-area) {
        -webkit-user-select: none;
        user-select: none;
      }
      // 编辑和预览区域
      :deep(.v-md-editor__right-area) {
        // 头部
        .v-md-editor__toolbar {
          -webkit-user-select: none;
          user-select: none;
          &-item {
            color: var(--editor__toolbarColor) !important;
            &--active,
            &--active:hover {
              background: var(--actice-editor__toolbar-backgroundColor) !important;
              color: var(--active-editor__toolbarColor) !important;
            }
          }
        }
        // 编辑区域
        .v-md-editor__editor-wrapper {
          .CodeMirror {
            background-color: var(--backgroundColor) !important;
            .CodeMirror-activeline-background {
              background-color: var(--enterBackgroundColor);
            }
          }
        }
        // 预览区域
        .v-md-editor__preview-wrapper {
          -webkit-user-select: none;
          user-select: none;
          .github-markdown-body {
            table {
              tr {
                background-color: var(--backgroundColor) !important;
              }
            }
            img {
              background-color: var(--backgroundColor) !important;
            }
          }
        }
      }
    }
  }
</style>
